package com.cg.service.impl;

import com.cg.dao.UserMapper;
import com.cg.dao.UserRoleMapper;
import com.cg.dto.*;
import com.cg.entity.User;
import com.cg.entity.UserRole;
import com.cg.service.UserService;
import com.cg.service.UserTokenService;
import com.cg.utils.MD5Utils;
import com.cg.vo.LoginUserVo;
import com.cg.vo.UserDepRoleVo;
import com.cg.vo.UserDetailVo;
import com.cg.vo.UserShowInfoVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * (User)表服务实现类
 *
 * @author chengong
 * @since 2023-12-01 11:49:44
 */
@Service("userService")
public class UserServiceImpl implements UserService {

    private final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserTokenService userTokenService;

    @Value("${userTokenTimeOut}")
    private Long userTokenTimeOut;

    @Value("${userTokenTime}")
    private Long userTokenTime;

    @Resource
    private UserRoleMapper userRoleMapper;

    /**
     * 用UUID生成codeNum
     */
    @Override
    public String createCodeNum() {
        String codeNum = UUID.randomUUID().toString().replace("-", "");
        return codeNum;
    }

    /**
     * 添加新用户
     * @param user:前端传过来要添加的用户信息
     */
    @Override
    public Integer createUser(User user) {
        Integer count = 0;
        try {
            //密码加密处理
            String passwordMySql = user.getPassword();
            String passwordMd5 = MD5Utils.MD5(passwordMySql);
            user.setPassword(passwordMd5);

            String codeNum = createCodeNum();
            user.setCodeNum(codeNum);

            count = userMapper.createUser(user);
        }catch (Exception e){
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 用户登录
     * @param user：前端传递过来的用户登录名和密码
     * @return：返回的数据
     */
    @Override
    public LoginUserVo login(User user) {
        LoginUserVo loginUserVo = userMapper.login(user);
        if(loginUserVo == null){
            return null;
        }
        //验证密码
        String loginUserPassword = loginUserVo.getPassword();//数据库里面的密码
        String password = user.getPassword();//获取用户输入的密码
        password = MD5Utils.MD5(password);//将用户输入的密码转换成MD5 格式
        if(!password.equals(loginUserPassword)){//两个MD5格式密码进行比较
            return null;
        }
        //保存到redis中
        //安全起见，显示的密码赋空值
        loginUserVo.setPassword("");
        userTokenService.setUserToken(loginUserVo);
        return loginUserVo;
    }

    @Override
    public LoginUserVo getUserByToken(String token) {
        //redis中的token是token:PC-jack-1-20231206122703-fb3e4a
        String[] arr = token.split("-");
        String timeStr = arr[3];
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date timeToken = null;
        Date now = null;
        Long dff = null;
        try {
            timeToken = simpleDateFormat.parse(timeStr);//Token中获取的时间
            now =  new Date();//当前的时间
            //当前的时间减去从Token中获取的时间差
            dff = now.getTime() - timeToken.getTime();
            //判断是否超过两小时
            if(dff > userTokenTimeOut*1000){
                //超过两小时
                return null;
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }
        //判断redis中是否存在用户信息
        LoginUserVo userByToken = userTokenService.getUserByToken(token);
        //判断redis中是否存在
        if(userByToken != null){
            //如果存在，则返回去用户信息
            //一个半小时刷新token
            if(dff > userTokenTime*1000){
                //删除之前的token
                userTokenService.deleteByToken(token);
                //生成新的用户信息保存到redis中并返回信息
                userTokenService.setUserToken(userByToken);
            }
            return userByToken;
        }
        //如果不存在，从MySql中查询
        //获取userId
        String userIdStr = arr[2];
        int userId = Integer.parseInt(userIdStr);
        userByToken = userMapper.queryUserByUserId(userId);
        //然后再将查询到的用户信息保存到redis中
        userTokenService.setUserToken(userByToken);

        return userByToken;
    }

    /**
     * 员工管理页面分页并按照名称模糊查询
     */
    @Override
    public PageInfo<UserDepRoleVo> queryUserByUserName(UserDepRoleDto userDepRoleDto) {
        PageHelper.startPage(userDepRoleDto.getPageNum(),userDepRoleDto.getPageSize());
        List<UserDepRoleVo> userDepRoleVos = userMapper.queryUserByUserName(userDepRoleDto.getUserName());
        PageInfo<UserDepRoleVo> pageInfo = new PageInfo<>(userDepRoleVos);
        return pageInfo;
    }

    /**
     * 用户授权
     * @param userRoleDto
     * @return
     */
    @Override
    public Integer createUserRole(UserRoleDto userRoleDto) {
        //先删除之前的
        userRoleMapper.deleteByUserId(userRoleDto.getUserId());
        //保存权限
        Integer userRole = userRoleMapper.createUserRole(userRoleDto);

        //删除所有的key值
        //TODO
        return userRole;
    }
    /**
     * 用户详情展示
     */
    @Override
    public UserDetailVo getUserByUserId(Integer userId) {

        return userMapper.getUserByUserId(userId);
    }

    /**
     * 启用/禁用
     */
    @Override
    public Integer updateUserState(Integer id) {
        User user = userMapper.selectById(id);
        Integer userState = user.getUserState();
        Integer count = 0;

        if(userState == 1){
            user.setUserState(0);
        }
        if(userState == 0){
            user.setUserState(1);
        }

        try {
            count = userMapper.updateUserState(user);
        }catch (Exception e){
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 修改员工信息
     * @param user
     * @return
     */
    @Transactional
    @Override
    public Integer updateUserByUserId(User user) {
        Integer count = 0;
        try {
            if(user.getPassword()!= null && !user.getPassword().equals("")){
                user.setPassword(MD5Utils.MD5(user.getPassword()));
                count = userMapper.updateUserByUserId(user);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 删除员工
     */
    @Override
    public Result deleteUserByUserId(Integer userId) {
        List<UserRole> userRoles = userRoleMapper.queryAllUserRoleByUserId(userId);
        if(userRoles == null || userRoles.size() == 0){
            //关联表中没有关联此员工的信息
            //可以删除
            Integer count = userMapper.deleteUserByUserId(userId);
            if(count <=0){
                return ResultUtils.returnFail("信息删除失败，可能存在异常");
            }
            return ResultUtils.returnSuccess();
        }
        //角色有绑定权限信息，
        //需要先删除绑定的权限信息，再进行删除操作
        return ResultUtils.returnResult(ResultEnum.FAIL_DELETE_ROLE);
    }

    /**
     * 根据用户id查询个人的详细信息
     */
    @Override
    public UserShowInfoVo queryUserInfo(Integer userId) {
        //从数据库中查询详细信息
        UserShowInfoVo userShowInfoVo = userMapper.queryUserInfo(userId);
        return userShowInfoVo;
    }

    /**
     * 验证登录名是否可用
     */
    @Override
    public Integer checkLoginUser(String loginUser) {
        Integer count = 0;
        try {
            count = userMapper.checkLoginUser(loginUser);
        }catch (Exception e){
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 修改密码
     */
    @Override
    public Integer setPassword(UpdateUserDto updateUserDto) {
        Integer count = 0;
        //验证密码是否一致
        //输入的之前的旧密码,(要做验证的密码)
        String passwordOld = updateUserDto.getPasswordOld();
        //输入的新密码(要修改的密码)
        String passwordNew = updateUserDto.getPassword();
        //获取id
        Integer id = updateUserDto.getId();
        //根据id查询对象
        LoginUserVo loginUserVo = userMapper.queryUserByUserId(id);
        //获取之前的密码,加密过得
        String password = loginUserVo.getPassword();
        if(!password.equals(MD5Utils.MD5(passwordOld))){
            return count;
        }
        updateUserDto.setPassword(MD5Utils.MD5(passwordNew));
        count = userMapper.setPassword(updateUserDto);
        return count;
    }

    /**
     * 修改用户登录名
     */
    @Override
    public Integer setLoginUser(User user) {
        Integer count = 0;
        try {
            count = userMapper.setLoginUser(user);
        }catch (Exception e){
            e.printStackTrace();
        }
        return count;
    }


}
